<?php

namespace app\services;

use app\traits\Page;
use plugin\admin\app\model\Exchange;
use plugin\admin\app\model\ExchangeApply;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserChat;
use plugin\admin\app\model\UserChatBlackList;
use plugin\admin\app\model\UserChatMessage;

class ChatService
{
    public static function newChat($exchangeId, $userId = null)
    {
        $exchangeInfo = Exchange::find($exchangeId);

        if (!$exchangeInfo) {
            throw new \Exception('不存在的交换');
        }

        if ($chatInfo = self::hasChat(get_user_id(), $exchangeInfo['user_id'])) {
            return $chatInfo['id'];
        }

        $chatId = UserChat::insertGetId([
            'name' => '',
            'last_message_info' => '',
            'user_id' => $userId ?? get_user_id(),
            'chat_user_id' => $exchangeInfo['user_id'],
            'un_read_count' => 0,
            'exchange_id' => $exchangeId,
            'created_time' => date('Y-m-d H:i:s'),
            'updated_time' => date('Y-m-d H:i:s'),
        ]);

        return $chatId;
    }

    public static function hasChat($userId, $chatUserId)
    {
        if ($chatInfo = UserChat::where('user_id', $userId)->where('chat_user_id', $chatUserId)->first()) {
            return $chatInfo;
        }

        return UserChat::where('chat_user_id', $userId)->where('user_id', $chatUserId)->first();
    }

    public static function chatList()
    {
        $chats = UserChat::where('user_id', get_user_id())->orWhere('chat_user_id', get_user_id())->get()->toArray();

        $chatUserIds = array_column($chats, 'chat_user_id');
        $userIds = array_column($chats, 'user_id');
        $exchangeIds = array_column($chats, 'exchange_id');

        $users = User::select(['id', 'nickname', 'avatar'])->whereIn('id', array_merge($chatUserIds, $userIds))->get()->toArray();
        $users = array_combine(
            array_column($users, 'id'),
            array_values($users)
        );

        $exchanges = Exchange::select(['id', 'thumbs', 'name', 'quality', 'status', 'is_up'])->whereIn('id', $exchangeIds)->get()->toArray();
        $exchanges = array_combine(
            array_column($exchanges, 'id'),
            array_values($exchanges)
        );

        foreach ($exchanges as $key=>$exchange) {
            $exchanges[$key]['status_text'] = Exchange::getStatusText($exchange);
        }

        $list = [];

        foreach ($chats as $chat) {

            if ($chat['user_id'] == get_user_id()) {
                $userInfo = $users[$chat['chat_user_id']];
            } else {
                $userInfo = $users[$chat['user_id']];
            }

            $list[] = [
                'id' => $chat['id'],
                'user_info' => $userInfo,
                'exchange_info' => $exchanges[$chat['exchange_id']],
                'last_message_info' => $chat['last_message_info'],
                'time' => date('m-d H:i:s', strtotime($chat['updated_time'])),
            ];
        }

        return $list;

    }

    public static function messageList($chatId, $page, $length = 50)
    {
        $chatInfo = UserChat::find($chatId);

        if (!$chatInfo) {
            throw new \Exception('不存在的会话');
        }

        if ($chatInfo['user_id'] != get_user_id() && $chatInfo['chat_user_id'] != get_user_id()) {
            throw new \Exception('非法访问');
        }

        $offset = ($page - 1) * $length;

        $query = UserChatMessage::where('chat_id', $chatId);

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->orderBy('created_time')->get()->toArray();

        $users = User::select(['id', 'nickname', 'avatar'])->whereIn('id', [$chatInfo['user_id'], $chatInfo['chat_user_id']])->get()->toArray();
        $users = array_combine(
            array_column($users, 'id'),
            array_values($users)
        );

        $exchangeInfo = Exchange::find($chatInfo['exchange_id']);

        foreach ($list as $key=>$item) {
            $list[$key]['is_self'] = $item['user_id'] == get_user_id();
            $list[$key]['user_info'] = $users[$item['user_id']];
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    public static function addToBlackList($userId)
    {
        if (!self::isInBlackList(get_user_id(), $userId)) {
            UserChatBlackList::insert([
                'user_id' => get_user_id(),
                'forbid_user_id' => $userId,
                'created_time' => date('Y-m-d H:i:s')
            ]);
        }
    }

    public static function removeFromBlackList($userId)
    {
        UserChatBlackList::where('user_id', get_user_id())->where('forbid_user_id', $userId)->delete();
    }

    public static function isInBlackList($userId, $forbidUserId)
    {
        return UserChatBlackList::where('user_id', $userId)->where('forbid_user_id', $forbidUserId)->count() > 0;
    }

    public static function addMessage($chatId, $messageType, $messageValue, $userId = null)
    {
        $chatInfo = UserChat::find($chatId);

        if (!$chatInfo) {
            throw new \Exception('不存在的会话');
        }

        $userId = $userId ?? get_user_id();

        if ($chatInfo['user_id'] != $userId && $chatInfo['chat_user_id'] != $userId) {
            throw new \Exception('非法访问');
        }

        if ($chatInfo['user_id'] == $userId && self::isInBlackList($chatInfo['chat_user_id'], $userId)) {
            throw new \Exception('消息已发出，但被对方拒绝');
        }

        if ($chatInfo['chat_user_id'] == $userId && self::isInBlackList($chatInfo['user_id'], $userId)) {
            throw new \Exception('消息已发出，但被对方拒绝');
        }

        $data = [
            'chat_id' => $chatId,
            'user_id' => $userId,
            'message_type' => $messageType,
        ];

        $name = '';
        if ($messageType == UserChatMessage::TYPE_TEXT) {
            $data['text'] = $messageValue;
            $name = $messageValue;
        } else if ($messageType == UserChatMessage::TYPE_IMAGE) {
            $data['thumb'] = $messageValue;
            $name = '[图片]';
        } else {
            if (ExchangeApply::where('id', $messageValue)->count() == 0) {
                throw new \Exception('不存在的申请');
            }

            $data['exchange_apply_id'] = $messageValue;

            if ($messageType == UserChatMessage::TYPE_APPLY_INFO) {
                $name = '[申请交换]';
            } else if ($messageType == UserChatMessage::TYPE_APPLY_AGREE) {
                $name = '[同意申请]';
            } else {
                $name = '[拒绝申请]';
            }
        }

        $data['created_time'] = date('Y-m-d H:i:s');

        UserChatMessage::insert($data);

        UserChat::where('id', $chatId)->update([
            'name' => $name,
            'last_message_info' => $name,
            'updated_time' => date('Y-m-d H:i:s')
        ]);
    }
}